import java.io.*;
import java.util.*;
public class WordListManager {
	
	WordTile wt;
	static HashMap<SpecialString,IndexWordTile> indexCol;
	static File colFp;
	static int freq;
	
	void makeWordtile(int docId,int paraId,	long paraLoc,long wordLoc,String word){
		
		
		wt = new WordTile(docId,paraId,paraLoc,wordLoc,word);
	}
	
	void writeWordtile(File dir){
		try{
			//open/create file word.txt for word
			File tileFP = new File(dir,wt.getWord());
			PrintWriter out = new PrintWriter(new FileWriter(tileFP,true));
			
			//writing data into file word.txt
			out.println(wt.toString());
			
			
			out.flush();
			out.close();
		}catch(Exception e){
			e.printStackTrace();
			
		}
	}
	
	
	//loading main Index file into memory(indexCol);
	static void loadIndexFile(File fp){
		try{
			colFp = fp;
			FileInputStream fis = new FileInputStream(fp.getPath()+"_IndexFile.ser");
			ObjectInputStream ois = new ObjectInputStream(fis);
			indexCol = (HashMap<SpecialString,IndexWordTile>) ois.readObject(); 
			ois.close();
			
			
			/*Iterator it = indexCol.keySet().iterator();
			while(it.hasNext()){
				SpecialString x = (SpecialString) it.next();
				(indexCol.get(x)).display();
			}*/
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	
	static int getFrequency(){
		//IndexWordTile iwt = indexCol.get(new SpecialString(word));
		//return iwt.getFreq();
		return freq;
		
	}
	//Returns array of WordTile objects for a given word and file pointer to collection file.
	static ArrayList<WordTile> getWordTiles(String word){
		File postFile = new File(colFp.getPath()+"_postFile.txt");
		ArrayList<WordTile> arr = new ArrayList<WordTile>(); 
		try{
			RandomAccessFile raf = new RandomAccessFile(postFile,"r");
		
			IndexWordTile iwt = indexCol.remove(new SpecialString(word));
			
			if(iwt == null)
				return null;	//no match found
			
			//Incrementing the frequency of words searched for and put back again in the hasmap
			iwt.incrementFreq();
			indexCol.put(new SpecialString(word),iwt);
			
			//frequency
			freq = iwt.freq;
			
			raf.seek(iwt.getAddr());
			int i = iwt.getOccurrence();
			while(i>0){
				String sentence = raf.readLine();
				String[] elements = sentence.split(" +");
				WordTile wt2 = new WordTile(Integer.parseInt(elements[0]),Integer.parseInt(elements[1]),Long.parseLong(elements[2]),
									Long.parseLong(elements[3]), elements[4]);
				arr.add(wt2);
				i--;
			}
			
			//Iterator it = indexCol.keySet().iterator();
			/*while(it.hasNext()){
				SpecialString x = (SpecialString) it.next();
				if (x.equals("god")){
				System.out.println(x.hash);
				System.out.println((new SpecialString(word)).hashCode());
				}
				//(indexCol.get(x)).display();
			}
			//iwt.display();
*/			
			
			
			
			raf.close();
			return arr;
		}catch(Exception e){
			e.printStackTrace();
		}
		
		
		return null;
	}
	
	//Returns array of WordTile objects for a given word and file pointer to collection file. , overloaded , used internally
	static ArrayList<WordTile> getWordTiles(String word, File colFp, String old){
		File dirIndex = new File(colFp.getPath()+"_Index"); //pointer to directory where are index files are present.
		File indexFile = new File(dirIndex,word);
		ArrayList<WordTile> arr = new ArrayList<WordTile>();
		WordTile wt2;
		if(indexFile == null){	//no word found, end of module
			return null;
		}
		try{
			//open file word.txt
			BufferedReader br = new BufferedReader(new FileReader(indexFile));
			String sentence;
			String[] elements;
			while((sentence = br.readLine())!=null){	//read lines one after another
				elements = sentence.split(" +");	//split the sentence into words
				wt2 = new WordTile(Integer.parseInt(elements[0]),Integer.parseInt(elements[1]),Long.parseLong(elements[2]),
						Long.parseLong(elements[3]), elements[4]);		//new word tile object for hold data for the query word
				arr.add(wt2);					//adding all word location data in array
			}
			
			br.close();
		
		}
		catch(Exception e){
			System.out.println("error here 123413231223");
			e.printStackTrace();
		}
		
		//System.out.println(indexFile.toPath())
		
		return arr;
	}
	void displayWordtile(){
		wt.display();
	}
	
	//serailizing collection holding main index file
	 static void serializeNow(File fp, HashMap<SpecialString,IndexWordTile> indexCol){
		try{
			FileOutputStream fs = new FileOutputStream(fp.getPath()+"_IndexFile.ser");
			ObjectOutputStream os = new ObjectOutputStream(fs);
		
			os.writeObject(indexCol);
			os.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	 
	static void writeIndexFile(){
		serializeNow(colFp,indexCol);
	}
	
	
	
	//return array of WordTile when a word is matched.
	
	
	//detecting a stop word from file english_stop_norm.txt
	//english_stop_norm.txt file contains lines of fixed length 22
	//redundant
	boolean stopWord(String word){
		//22
		File stopFP = Settings.stopFP; 			//file pointer to english_stop_norm.txt
		String strFromFile; 
		long noOfWords,upperOffset,lowerOffset,currentOffset=1;
		RandomAccessFile raf;
		
		try{
			//open file in random access mode
			raf = new RandomAccessFile(stopFP,"r");
			lowerOffset = noOfWords= (raf.length()/22)-1;		//calculating line no of last line
			upperOffset = 0;									// beginning of file.
			//String up,low;
			
			//binary search in the file to detect stop word.
			while(lowerOffset-upperOffset > 1){
				currentOffset = (int)(lowerOffset + upperOffset)/2;
				raf.seek(currentOffset*22);
				strFromFile = raf.readLine().trim(); 
				
				/*raf.seek(lowerOffset*22);
				low = raf.readLine().trim();
				
				raf.seek(upperOffset*22);
				up = raf.readLine().trim();
				
				System.out.println(low+" "+word+" "+up);*/
				
				if(strFromFile.compareTo(word)==0){
					
					raf.close();
					
					return true;
				}
				else if(word.compareTo(strFromFile)<0) {
					
					lowerOffset = currentOffset;
				}
				else if(word.compareTo(strFromFile)>0){
				
					upperOffset = currentOffset;
				}
			}
			
			//check if line no (=upperOffset) is a stop word
			raf.seek(upperOffset*22);
			strFromFile = raf.readLine().trim();
			if(strFromFile.compareTo(word)==0){
				raf.close();
				return true;
			}
			
			//check if line no (=lowerOffset) is a stop word
			raf.seek(lowerOffset*22);
			strFromFile = raf.readLine().trim();
			if(strFromFile.compareTo(word)==0){
				raf.close();
				return true;
			}
			
			raf.close();
			return false;		//no match found.
			
			
			
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			
		}
		
		return false;
	}
	
	
	//removing punctuation marks and making all to lowercase.
	String cleanWord(String word){
		//cleaning the word , making all to lowercase, removing punctuation marks
		
		
		//word end. = end
		char punct = word.charAt(word.length()-1);
		if((punct >= 48 && punct <=57)||(punct >= 65 && punct <=90)||(punct >=97 && punct<=122)  ){
			
		}
		else{
			word = word.substring(0,word.length()-1);
		}
		
		//word end). = end
		punct = word.charAt(word.length()-1);
		if((punct >= 48 && punct <=57)||(punct >= 65 && punct <=90)||(punct >=97 && punct<=122)  ){
			
		}
		else{
			word = word.substring(0,word.length()-1);
		}
		
		//word (end = end
		punct = word.charAt(0);
		if((punct >= 48 && punct <=57)||(punct >= 65 && punct <=90)||(punct >=97 && punct<=122)  ){
			
		}
		else{
			word = word.substring(1);
		}
		//word there's = there
		if(word.length()>1){
			punct = word.charAt(word.length()-2);
			if((punct >= 48 && punct <=57)||(punct >= 65 && punct <=90)||(punct >=97 && punct<=122)  ){
				
			}
			else{
				word = word.substring(0,word.length()-2);
			}
		}
		word=word.toLowerCase();
	//	System.out.println(word);
		return word;
	}
}

